package cn.yunyichina.provider.message.service.impl;

import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.common.ResponseEnum;
import cn.yunyichina.provider.framework.dubbo.service.*;
import cn.yunyichina.provider.framework.exception.CallException;
import cn.yunyichina.provider.iface.entity.ErrorCodeDefine;
import cn.yunyichina.provider.iface.entity.PersonalUser;
import cn.yunyichina.provider.iface.entity.PersonalUserOpenid;
import cn.yunyichina.provider.iface.entity.base.MedicalCardVo;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.base.OrgApp;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.pay.PaymentSettingResponse;
import cn.yunyichina.provider.message.dao.*;
import cn.yunyichina.provider.message.entity.*;
import cn.yunyichina.provider.message.thread.MessagePushThreadPool;
import cn.yunyichina.provider.message.thread.MsgAppPushRunnable;
import cn.yunyichina.provider.message.utils.MsgTemplateUtils;
import cn.yunyichina.provider.message.vo.MsgTemplateListVo;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通用消息发送
 * 
 */
@Service("msgServiceImpl")
public class MsgServiceImpl {
	private static Logger logger = LoggerFactory.getLogger(MsgServiceImpl.class);
	
	@Autowired
	MessageRouterServiceImpl messageRouterServiceImpl;
	
	@Autowired
	private TextTemplateDao textTemplateDao;
	
	@Autowired
	private OrgAppTemplateDao orgAppTemplateDao;
	
	@Autowired
	private TmpTemplateDao tmpTemplateDao;
	
	@Autowired
	private TmpTemplateListDao tmpTemplateListDao;;
	
	@Autowired
	private MessageTemplateDao messageTemplateDao;

	@Autowired
	private MsgSmsServiceImpl msgSmsService;

	@Autowired
	private ImageTemplateDao imageTemplateDao;

	@Autowired
	private ImageTemplateListDao imageTemplateListDao;

	@Resource
	private MsgAppServiceImpl msgAppServiceImpl;
	
	@Resource
	ResendRuleServiceImpl resendRuleServiceImpl;



	/**
	 * 获取骨科应用对应的消息模板
	 * yyt.message.msg.app.template.bone.get
	 * @param json
	 * @return
	 */
	public ResponseObject getMsgAppTemplateBone(String json) {
		logger.info("MsgServiceImpl.getMsgAppTemplateBone->获取骨科应用对应的消息模板json入参 -> {}", json);

		OrgAppTemplate orgAppTemplate=JsonUtils.parseObject(json,OrgAppTemplate.class);
		if(orgAppTemplate==null){
			throw new CallException("8001", "获取骨科应用对应的消息模板信息出错");
		}
		ResponseObject response = new ResponseObject();
		try {
			List<OrgAppTemplate> orgAppTemplateList=orgAppTemplateDao.select(orgAppTemplate);
			logger.info("MsgServiceImpl.getMsgAppTemplateBone->获取骨科应用对应的消息模板json出参 {}", JSON.toJSONString(orgAppTemplateList));
			response.setResultObject( orgAppTemplateList);
		} catch (CallException e) {
			logger.error("MsgServiceImpl.getMsgAppTemplateBone->CallException", e);
			response.buildResultCodeAndMessage(
					ResponseEnum.Common.FAILURE.getCode(),
					ResponseEnum.Common.FAILURE.getMessage()
			);
		}
		return response;
	}



	/**
	 * 微信小程序模板消息发送
	 * @param toUser
	 * @param templateCode
	 * @param page 可空
	 * @param formId
	 * @param data
	 * @param emphasisKeyword 可空
	 * @param orgAppCode
	 * @param devOrgCode 可空
	 * @param userType 
	 * @return
	 */
	public String sendMsgSmallTemplateMessageReal(String toUser,String templateCode,String page,String formId,String data,String emphasisKeyword,String orgAppCode,String devOrgCode,int userType) {
		try {
			logger.debug("sendMsgSmallTemplateMessage:"+toUser);
		
			JSONObject param = new JSONObject();
			
			param.put("org_app_code",orgAppCode);
			param.put("org_code",devOrgCode);
			param.put("to_user",toUser);
			param.put("template_code",templateCode);
			param.put("form_id",formId);
			
			param.put("userType",userType);
			
			param.put("msg_content", JsonUtils.parseObject(StringUtils.isBlank(data) ? "{}" : data));
			param.put("emphasis_keyword", StringUtils.isBlank(emphasisKeyword) ? "" : emphasisKeyword);
			param.put("page", StringUtils.isBlank(page) ? "" : page);

			param.put("platform_type", 1);
			
			
			OrgAppTemplate orgAppTemplate = getMatchOrgAppTemplate(param.getString("template_code"),param.getString("org_app_code"),param.getString("org_code"),1,3);
			TmpTemplate tmpTemplate = getTmpTemplate(param.getString("template_code"),param.getString("org_app_code"),param.getString("org_code"),1);
			Short platformTypeShort = orgAppTemplate.getPlatformType();
			param.put("platform_type", platformTypeShort);
			
			param.put("template_id", orgAppTemplate.getPayTemplateId());
			
			param.put("head_color",tmpTemplate.getTopColor());
			
			if (StringUtils.isBlank(param.getString("page"))) {
				param.put("page", tmpTemplate.getUrl());
			}
			param.put("page",parseUrl(param.getString("page"),param));
			
			//解析和设置内容参数
			setMsgContentForWechat(param,tmpTemplate.getListTmpTemplateList());
			
			param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 1));
			
			
			
			//解析和设置内容参数
			setMsgContentForWechat(param);

			//解析和设置发送的用户
			setToUser(param,"wechat");
			
			param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 1));
			
			logger.debug("yyt.wechatpay.wechat.message.template.by.access.token.send调用参数："+JsonUtils.toJsonString(param));
			
			//微信发送
			Response messageResponse = WechatPayService.callHumpFromInternal("yyt.wechatpay.wechat.message.template.by.access.token.send", JsonUtils.toJsonString(param));
			if ("0".equals(messageResponse.getResultCode())) {
				return "ok";
			}
			else {
				return messageResponse.getResultMessage();
			}

	
			
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
	}
	
	/**
	 * 微信小程序模板消息发送
	 * yyt.message.msg.small.template.message.send
	 * @param to_user
	 * @param template_code
	 * @param page 可空
	 * @param formId
	 * @param data
	 * @param emphasisKeyword 可空
	 * @param orgAppCode
	 * @param devOrgCode 可空
	 * @param userType 
	
	 * @return
	 */
	public String sendMsgSmallTemplateMessage(String strJson) {
		logger.debug("sendSmallTemplateMessage:"+strJson);
		JSONObject param = JsonUtils.parseObject(strJson);
		
		//参数验证
		validParam(param,"to_user,template_code,form_id,org_app_code");
		
		String orgAppCode=param.getString("org_app_code");
		String devOrgCode=param.getString("org_code");
		String toUser = param.getString("to_user");
		String templateCode=param.getString("template_code");
		String fromId=param.getString("form_id");
		int userType = param.getIntValue("user_type");
		
		String data=param.containsKey("data") ? JsonUtils.toJsonString(param.get("data")) : "";
		String emphasisKeyword=param.containsKey("emphasis_keyword") ? param.getString("emphasis_keyword") : "";
		String page=param.containsKey("page") ? param.getString("page") : "";
		
		return sendMsgSmallTemplateMessageReal(toUser, templateCode, page, fromId, data, emphasisKeyword, orgAppCode, devOrgCode,userType);
		
	}

	public static final String CACHE_KEY_NOT_EXIST = "nil";
	
	/**
	 * 检查从cache里获取的字符串值是否有效
	 * @param strJson 从cache里获取的字符串值
	 */
	public static boolean isValidCacheValue(String value) {
		if (StringUtils.isNotEmpty(value) && ! value.equalsIgnoreCase(CACHE_KEY_NOT_EXIST)) {
			return true;
		}
		return false;
	}
	/**
	 * 参数非空验证
	 * @param param
	 * @param fieldNames
	 */
	private void validParam(JSONObject param,String fieldNames) {
		if (StringUtils.isNotBlank(fieldNames)) {
			String[] arrFieldName = fieldNames.split(",");
			for (String fieldName : arrFieldName) {
				if (StringUtils.isBlank(param.getString(fieldName.trim()))) {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM,"参数异常"+fieldName.trim());
				}
			}
		}
	}
	
	/**
	 * 获取匹配的消息发送模板(新库)
	 * 
	 * @param templateCode
	 * @param appCode
	 * @param orgCode 可以为空
	 * @param platformType 0不限定，1微信，2支付宝
	 * @param libraryTemplateType 模板类型 1文本，2图文，3模板
	 * @return
	 */
	private OrgAppTemplate getMatchOrgAppTemplate(String templateCode,String appCode,String orgCode,Integer platformType,Integer libraryTemplateType) {
		logger.debug("getTmpTemplate:templateCode={},appCode={},orgCode={},platformType={},libraryTemplateType={}",templateCode,appCode,orgCode,platformType,libraryTemplateType);

		OrgAppTemplate orgAppTemplate = orgAppTemplateDao.selectForMatch(templateCode, appCode, orgCode,platformType,libraryTemplateType);
		if (orgAppTemplate == null ) {
			logger.error( "找不到模板模板编码("+templateCode+")");
			throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "找不到模板模板编码("+templateCode+")");
		} 
		
		return orgAppTemplate;
	}
	
	public TmpTemplate getTmpTemplate(String templateCode,String appCode,String orgCode,Integer platformType) {
		logger.debug("getTmpTemplate:templateCode={},appCode={},orgCode={},platformType={}",templateCode,appCode,orgCode,platformType);

		OrgAppTemplate orgAppTemplate = orgAppTemplateDao.selectForMatch(templateCode, appCode, orgCode,platformType,3);
		if (orgAppTemplate == null ) {
			logger.error( "找不到模板模板编码("+templateCode+")");
			throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "找不到模板模板编码("+templateCode+")");
		} 
		
		TmpTemplate tmpTemplate = new TmpTemplate();
		tmpTemplate.setTemplateCode(orgAppTemplate.getLibraryTemplateCode());
		List<TmpTemplate> listTmpTemplate = tmpTemplateDao.select(tmpTemplate);
		if (listTmpTemplate == null || listTmpTemplate.size() == 0) {
			logger.error("找不到模板内部模板编码("+templateCode+")");
			throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "找不到模板内部模板编码("+templateCode+")");
		}
		
		tmpTemplate = listTmpTemplate.get(0);
		tmpTemplate.setPayTemplateId(orgAppTemplate.getPayTemplateId());
		TmpTemplateList tmpTemplateList = new TmpTemplateList();
		tmpTemplateList.setTmpTemplateCode(tmpTemplate.getTemplateCode());
		List<TmpTemplateList> listTmpTemplateList = tmpTemplateListDao.select(tmpTemplateList);
		tmpTemplate.setListTmpTemplateList(listTmpTemplateList);
		
		logger.debug("获取的tmpTemplate："+JsonUtils.toJsonString(tmpTemplate));
		return listTmpTemplate.get(0);
	}
	
	private TextTemplate getTextTemplate(String templateCode,String appCode,String orgCode,Integer platformType) {
		logger.debug("getTmpTemplate:templateCode={},appCode={},orgCode={},platformType={}",templateCode,appCode,orgCode,platformType);

		TextTemplate textTemplate = null;
		OrgAppTemplate orgAppTemplate = getMatchOrgAppTemplate(templateCode,appCode,orgCode,platformType,1);
		String textTemplateCode = orgAppTemplate.getLibraryTemplateCode();
		if (StringUtils.isNotBlank(textTemplateCode)) {
			textTemplate = new TextTemplate();
			textTemplate.setTemplateCode(textTemplateCode);
			List<TextTemplate> listTextTemplate = textTemplateDao.select(textTemplate);
			if ( ! CollectionUtils.isEmpty(listTextTemplate)) {
				textTemplate = listTextTemplate.get(0);
			}
			else {
				throw new CallException(ErrorCodeDefine.MESSAGE_VALUE, "找不到内部文本模板：templateCode="+textTemplateCode);
			}
		}
		else {
			throw new CallException(ErrorCodeDefine.MESSAGE_VALUE, "文本模板没有定义：platformTemplateCode="+templateCode);
		}
		return textTemplate;
	}

	/**
	 * yyt.message.msg.text.template.get
	 * @param strJson
	 * @return
	 */
	public Response getMsgTextTemplate(String strJson) {
		logger.info("获取文本消息getMsgTextTemplate->strJson={}",strJson);
		TextTemplate textTemplate = JsonUtils.parseObject(strJson,TextTemplate.class);
		Response response = new Response();
		if (textTemplate!=null||StringUtils.isNotBlank(textTemplate.getTemplateCode())) {
			List<TextTemplate> listTextTemplate = textTemplateDao.select(textTemplate);
			if ( ! CollectionUtils.isEmpty(listTextTemplate)) {
				textTemplate = listTextTemplate.get(0);
				logger.info("获取文本消息getMsgTextTemplate->response={}",JSON.toJSONString(textTemplate));
				response.setResult(JsonUtils.toJsonString(textTemplate));
			} else {
				response.setResultCodeAndMessage(ErrorCodeDefine.MESSAGE_VALUE , "找不到内部文本消息模板:textTemplateCode="
						+textTemplate.getTemplateCode());
			}
		} else {
			response.setResultCodeAndMessage(ErrorCodeDefine.MESSAGE_VALUE , "文本消息模板入参textTemplateCode或textTemplate对象为空");
		}
		return response;
	}
	/**
	 * 指定平台（orgAppCode）发送模板消息 
	 * @param org_app_code
	 * @param org_code 可以空
	 * @param platformType
	 * @param userType
	 * @param toUser
	 * @param templateCode
	 * @param url
	 * @param msgContent
	 */
	private String sendMsgTemplateByAppCode(String strJson) {
		boolean sendSuccessFlag = false;
		JSONObject param = null;
		try {
			logger.debug("sendMsgTemplate:"+strJson);
			param = JsonUtils.parseObject(strJson);			
			param.put("code", param.getString("template_code"));
			
			String platformType = param.getString("platform_type").trim();
			if (platformType.equals("0")) {
				//获得需要发送消息的平台
//				param.put("platform_code","");
				throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "请指定平台类型");
			}
			else {
				if (param.containsKey("org_app_code") && StringUtils.isNotBlank(param.getString("org_app_code"))) {
					OrgApp orgApp = BaseService.getBaseClient().getOrgAppByAppCode(param.getString("org_app_code"));
					if (orgApp.getOrgAppType() == 3) {
						return sendMsgTemplateApp(strJson);
					}
				}
				else if (platformType.startsWith("1")) {
					param.put("platform_code", "wechat");
				}
				else if (platformType.startsWith("2")) {
					param.put("platform_code", "alipay");
				}
				else {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "平台类型错误");
				}
			}
			
			//参数验证
			validParam(param,"org_app_code,platform_type,user_type,template_code");
			
			String resendRuleId = param.containsKey("resend_rule_id") ? param.getString("resend_rule_id") : "";
			if ( ! StringUtils.isBlank(resendRuleId)) {
				ResendRule resendRule = resendRuleServiceImpl.getResendRule(resendRuleId);
				if (resendRule == null) {
					throw new CallException(ErrorCodeDefine.MESSAGE_NOT_FIND_RESEND_RULE, "无法获取消息重发规则");
				}
				param.put("resend_rule", resendRule);
			}
			
			
			OrgAppTemplate orgAppTemplate = getMatchOrgAppTemplate(param.getString("template_code"),param.getString("org_app_code"),param.getString("org_code"),Integer.parseInt(platformType.substring(0,1)),3);
			TmpTemplate tmpTemplate = getTmpTemplate(param.getString("template_code"),param.getString("org_app_code"),param.getString("org_code"),Integer.parseInt(platformType.substring(0,1)));
			Short platformTypeShort = orgAppTemplate.getPlatformType();
			param.put("platform_type", platformTypeShort);
			if (platformTypeShort == 2) {
				param.put("template_id", orgAppTemplate.getPayTemplateId());
				
				param.put("head_color",tmpTemplate.getTopColor());
				
				
				if (StringUtils.isBlank(param.getString("url"))) {
					param.put("url", tmpTemplate.getUrl());
				}

				param.put("url",parseUrl(param.getString("url"),param));
				
				//解析和设置内容参数
				setMsgContentForAlipay(param,tmpTemplate.getListTmpTemplateList());

				//解析和设置发送的用户
				setToUser(param,"alipay");
				
				param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 2));
				
				logger.debug("yyt.alipay.alipaymessage.template.send调用参数："+JsonUtils.toJsonString(param));
				
				AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.template.send", JsonUtils.toJsonString(param));
			}
			else if (platformTypeShort == 1) {
				param.put("template_id", orgAppTemplate.getPayTemplateId());
				
				param.put("head_color",tmpTemplate.getTopColor());
				
				if (StringUtils.isBlank(param.getString("url"))) {
					param.put("url", tmpTemplate.getUrl());
				}

				param.put("url",parseUrl(param.getString("url"),param));
				
				//解析和设置内容参数
				setMsgContentForWechat(param,tmpTemplate.getListTmpTemplateList());

				//解析和设置发送的用户
				setToUser(param,"wechat");
				
				param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 1));
				
				logger.debug("yyt.wechatpay.wechat.message.template.send调用参数："+JsonUtils.toJsonString(param));
				
				//微信发送
				WechatPayService.callHumpFromInternal("yyt.wechatpay.wechat.message.template.send", JsonUtils.toJsonString(param));
			}
		
			sendSuccessFlag = true;
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
		finally {
			if (param != null) {
				String smsMsgContent = JsonUtils.toJsonString(param.get("sms_msg_content"));
	        	if ( ! sendSuccessFlag) {
	        		sendSms(smsMsgContent);
				}
			}
		}
	}
	public static void sendSms(String smsMsgContent) {
		if (StringUtils.isNotBlank(smsMsgContent)) {
			try {
				JSONObject param = JsonUtils.parseObject(smsMsgContent);
				String mobile = param.getString("sms_mobile");
				if (StringUtils.isNotBlank(mobile)) {
					MessageService.sendSms(smsMsgContent);
				}
				
			}
			catch (Exception ex) {
				logger.error("发送短信错误:"+smsMsgContent,ex);
			}
		}
	}
	/**
	 * 发送医疗挂号通知
	 * yyt.message.msg.reg.notify.send
	 * @param org_app_code
	 * @param org_code
	 * @param strJson RegNotify对象
	 * @return
	 */
	public String sendMsgRegNotify(String strJson) {
		try {
			logger.debug("sendMsgRegNotify:"+strJson);
			JSONObject param = JsonUtils.parseObject(strJson);
			if (StringUtils.isNotBlank(param.getString("org_code"))) {
				param.put("hospital_code",param.getString("org_code"));
			}
			
			//参数验证
			validParam(param,"org_app_code,user_id,operate,third_no,patient_name,hos_info,dept_info,doctor_info,treat_date,biz_type,order_link");
			validParam(JsonUtils.parseObject(param.get("hos_info")),"code,name,phone");
			validParam(JsonUtils.parseObject(param.get("dept_info")),"code,name,location");
			validParam(JsonUtils.parseObject(param.get("doctor_info")),"code,name,sex");
			
			if (( ! StringUtils.isBlank(param.getString("notify_time")) )&& ErrorCodeDefine.YYYYMMDDHHMMSS.parse(param.getString("notify_time")).before(Calendar.getInstance().getTime())) {
				throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "通知时间必须大于当前日期");
			}
			
			if (ErrorCodeDefine.YYYYMMDDHHMMSS.parse(param.getString("treat_date")).before(Calendar.getInstance().getTime())) {
				throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "就诊时间必须大于当前日期");
			}
			
			if (StringUtils.isEmpty(param.getString("line_no"))) {
				throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "请输入排队号");
			}
			
			param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 2));
			
			logger.debug("yyt.alipay.alipaymessage.reg.notify.send调用参数："+JsonUtils.toJsonString(param));
			
			AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.reg.notify.send", JsonUtils.toJsonString(param));
			
			return "ok";
		} catch (CallException ce) {
			logger.error("发送医疗挂号通知异常",ce);
			throw ce;
		} catch (Exception e) {
			logger.error("发送医疗挂号通知异常",e);
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送医疗挂号通知异常",e);
		}
	}
	
	/**
	 * 
	 * @param appCode
	 * @param orgCode 可以为空
	 * @param platformType 1微信，2支付宝，3APP
	 * @return
	 */
	public PaymentSettingResponse getPaymentSetting(String appCode,String orgCode,Integer platformType) {
		MessageRouter messageRouter = messageRouterServiceImpl.selectRouterForMatch(appCode, orgCode, platformType);
		if (messageRouter == null) {
			throw new CallException(ErrorCodeDefine.MESSAGE_VALUE,"无法找到路由");
		}
		String paymentSettingId = messageRouter.getPaymentSettingId();
		
		ResCommon<PaymentSettingResponse> responsePayment= PayService.getPayClient().getPaymentSettingById(paymentSettingId);
		logger.debug("获取的app信息："+JsonUtils.toJsonString(responsePayment));
		if ( ! "0".equals(responsePayment.getResultCode()) || responsePayment.getResult() == null) {
			logger.error("无法获得PaymentSetting信息:paymentSettingId"+paymentSettingId);
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON,"无法获得APPID信息");
		}
		
		PaymentSettingResponse paymentSettingResponse = responsePayment.getResult();
		
		return paymentSettingResponse;

	}
	
	/**
	 * 发送模板消息
	 * yyt.message.msg.template.send
	 * @param hospitalCode
	 * @param platformType
	 * @param userType
	 * @param toUser
	 * @param templateCode
	 * @param url
	 * @param msgContent
	 */
	public String sendMsgTemplate(String strJson) {
		boolean sendSuccessFlag = false;
		JSONObject param = null;
		try {
			logger.debug("sendMsgTemplate:"+strJson);
			param = JsonUtils.parseObject(strJson);
			
			param.put("code", param.getString("template_code"));
			
			String platformType = param.getString("platform_type").trim();
			if (platformType.equals("0")) {
				//获得需要发送消息的平台
				param.put("platform_code","");
			}
			else {
				
				if (param.containsKey("org_app_code") && StringUtils.isNotBlank(param.getString("org_app_code"))) {
					OrgApp orgApp = BaseService.getBaseClient().getOrgAppByAppCode(param.getString("org_app_code"));
					if (orgApp.getOrgAppType() == 3) {
						return sendMsgTemplateApp(strJson);
					}
				}
				else if (platformType.startsWith("1")) {
					param.put("platform_code", "wechat");
				}
				else if (platformType.startsWith("2")) {
					param.put("platform_code", "alipay");
				}
				else {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "平台类型错误");
				}
			}
			

			//根据orgAppCode发送模板消息
			if (param.containsKey("org_app_code") && StringUtils.isNotBlank(param.getString("org_app_code"))) {
				sendSuccessFlag = true;
				return sendMsgTemplateByAppCode(strJson);
			}
			
			//参数验证
			validParam(param,"hospital_code,platform_type,user_type,template_code");

			List<MessageTemplate> listMessageTemplate = messageTemplateDao.findTemplateForSend(param.getString("template_code"),param.getString("hospital_code"),param.getString("platform_code"));
			logger.debug("listMessageTemplate:"+JsonUtils.toJsonString(listMessageTemplate)+",to_user="+param.getString("to_user"));
			
			if (listMessageTemplate == null || listMessageTemplate.size() == 0) {
				return "没有找到匹配的消息模板";
			}
			
			String resendRuleId = param.containsKey("resend_rule_id") ? param.getString("resend_rule_id") : "";
			if ( ! StringUtils.isBlank(resendRuleId)) {
				ResendRule resendRule = resendRuleServiceImpl.getResendRule(resendRuleId);
				if (resendRule == null) {
					throw new CallException(ErrorCodeDefine.MESSAGE_NOT_FIND_RESEND_RULE, "无法获取消息重发规则");
				}
				param.put("resend_rule", resendRule);
			}
			
			String strParamBak = JsonUtils.toJsonString(param);
			int sendIndex = 0;
			
			for (MessageTemplate messageTemplate : listMessageTemplate) {
				//避免循环参数冲突
				if (sendIndex > 0) {
					param = JsonUtils.parseObject(strParamBak);
				}
				sendIndex++;
				
				String platformCode = messageTemplate.getPlatformCode();
				if (platformCode.equals("alipay")) {
					param.put("template_id", messageTemplate.getTemplateId());
					
					param.put("head_color",messageTemplate.getHeadColor());
					
					if (StringUtils.isBlank(param.getString("url"))) {
						param.put("url", messageTemplate.getUrl());
					}

					param.put("url",parseUrl(param.getString("url"),param));
					
					//解析和设置内容参数
					setMsgContentForAlipay(param);

					//解析和设置发送的用户
					setToUser(param,"alipay");
					
					logger.debug("yyt.alipay.alipaymessage.template.send调用参数："+JsonUtils.toJsonString(param));
					
					AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.template.send", JsonUtils.toJsonString(param));
				}
				else if (platformCode.equals("wechat")) {
					param.put("template_id", messageTemplate.getTemplateId());
					
					if (StringUtils.isBlank(param.getString("url"))) {
						param.put("url", messageTemplate.getUrl());
					}

					param.put("url",parseUrl(param.getString("url"),param));
					
					//解析和设置内容参数
					setMsgContentForWechat(param);

					//解析和设置发送的用户
					setToUser(param,"wechat");
					
					logger.debug("yyt.wechatpay.wechat.message.template.send调用参数："+JsonUtils.toJsonString(param));
					
					//微信发送
					WechatPayService.callHumpFromInternal("yyt.wechatpay.wechat.message.template.send", JsonUtils.toJsonString(param));
					
				}
				
			}
			sendSuccessFlag = true;
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
		finally {
			if (param != null) {
				String smsMsgContent = JsonUtils.toJsonString(param.get("sms_msg_content"));
	        	if ( ! sendSuccessFlag) {
	        		sendSms(smsMsgContent);
				}
			}
        	
		}
	}
	/**
	 * 发送app消息<br>
	 * yyt.message.msg.template.app.send
	 * @param strJson org_app_code,platform_type,user_type,template_code,msg_content,org_code<br>
	 * msg_content格式(Map<String,String>对象)：{name:"name1","value":"value1"}
	 * @return
	 */
	public String sendMsgTemplateApp(String strJson) {
		try {
			logger.debug("sendMsgTemplateApp:"+strJson);
			JSONObject param = JsonUtils.parseObject(strJson);
			//参数验证
			validParam(param,"org_app_code,platform_type,user_type,template_code");
			
			//解析和设置内容参数
			setMsgContentForApp(param);

			//解析和设置发送的用户
//			setToUser(param,"app");
			
			logger.debug("调用参数："+JsonUtils.toJsonString(param));
			
			MessagePushThreadPool.messageThreadPool.execute(new MsgAppPushRunnable(strJson));
			
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
	}
	
	
	
	
	public static void main(String[] argv) {
		JSONObject object=new JSONObject();
		object.put("order_no",1115);
		object.put("url","abc.ed.com");
		parseUrl("http://{{url}}?order_no={{order_no}}",object);
	}
	/**
	 * 解析并且给url的参数赋值,如http://abc.ed.com?order_no={{order_no}}
	 * @param url 
	 * @param param 包含参数值的对象
	 * @return
	 */
	public static String parseUrl(String url,JSONObject param) {
		
		logger.info("parseUrl入参："+url);
		if (StringUtils.isBlank(url)) {
			return url;
		}
		
		if (url.indexOf("{{")> 0) {
			Pattern p = Pattern.compile("(?i)\\{\\{(\\s*[\\w_\\d]+\\s*)\\}\\}");
			Matcher m = p.matcher(url);
			StringBuffer sb = new StringBuffer();
			while (m.find()) {
				String fieldName = m.group(1).trim().toLowerCase();
				if (param.containsKey(fieldName)) {
					m.appendReplacement(sb, param.getString(fieldName));
				}
				else {
					logger.error(fieldName+"参数未传入值");
//					m.appendReplacement(sb, "null");
					//如果参数没有传入，返回空串，结果是模板点击失效
					return "";
//					throw new CallException(ErrorCodeDefine.MESSAGE_VALUE, fieldName+"参数未传入值");
				}
				
				
			}
			m.appendTail(sb);
			url = sb.toString();
		}
		logger.info("parseUrl后："+url);
		return url;
	}
	/**
	 * 设置模板内容--alipay
	 * @param param
	 */
	private void setMsgContentForAlipay(JSONObject param) {
		List<JSONObject> listContent = new ArrayList<JSONObject>();
		String msgContent = param.getString("msgContent");
		if (StringUtils.isNotBlank(msgContent)) {
			
//			JSONObject jsonContent = JsonUtils.parseObject(msgContent);
			JSONObject jsonContent = JSONObject.parseObject(msgContent);
			Iterator<String> it = jsonContent.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				JSONObject node = jsonContent.getJSONObject(key);
				node.put("node", key);
				node.put("font_color", node.get("color"));
				listContent.add(node);
			}
		}

		param.put("list_msg_template_content", listContent);
	}
	
	/**
	 * 新模板方式，msg_content只是一个key/value的Map对象即可，其中key为模板内容里定义的{{key}}
	 * @param param
	 * @param listNode
	 */
	private void setMsgContentForAlipay(JSONObject param,List<TmpTemplateList> listNode) {
		String msgContent = param.getString("msg_content");
		if (StringUtils.isNotBlank(msgContent)) {
			JSONObject jsonContent = JSONObject.parseObject(msgContent);
			List<JSONObject> listContent = new ArrayList<JSONObject>();
			if (listNode != null && listNode.size() > 0) {
				for (TmpTemplateList node : listNode) {
					String value = node.getValue();
					value = value == null ? "" : value;

					Iterator<String> it = jsonContent.keySet().iterator();
					while (it.hasNext()) {
						String key = it.next();
						value = value.replaceAll("(?i)\\{\\{\\s*"+key+"\\s*\\}\\}", jsonContent.getString(key));
					}
					
					JSONObject newNode = new JSONObject();
					newNode.put("node", node.getNode());
					newNode.put("font_color", node.getFontColour());
	
					newNode.put("value",value);
					
					listContent.add(newNode);
					
				}
			}
			param.put("list_msg_template_content", listContent);
		}
		
	}
	/**
	 * 设置模板内容--wechat
	 * @param param
	 */
	private void setMsgContentForWechat(JSONObject param) {
		Map<String,Object> map = new HashMap<>();
		String msgContent = param.getString("msgContent");
		if (StringUtils.isNotBlank(msgContent)) {
			
//			JSONObject jsonContent = JsonUtils.parseObject(msgContent);
			JSONObject jsonContent = JSONObject.parseObject(msgContent);
			Iterator<String> it = jsonContent.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				JSONObject node = jsonContent.getJSONObject(key);
				map.put(key, node);
			}
		}

		param.put("msg_content", JSONObject.toJSONString(map));
	}
	/**
	 * 新模板方式，msg_content只是一个key/value的Map对象即可，其中key为模板内容里定义的{{key}}
	 * @param param
	 */
	private void setMsgContentForWechat(JSONObject param,List<TmpTemplateList> listNode) {
	
		Map<String,Object> map = new HashMap<>();
		String msgContent = param.getString("msg_content");
		if (StringUtils.isNotBlank(msgContent)) {
			JSONObject jsonContent = JSONObject.parseObject(msgContent);
			if (listNode != null && listNode.size() > 0) {
				for (TmpTemplateList node : listNode) {
					
					String value = node.getValue();
					value = value == null ? "" : value;

					Iterator<String> it = jsonContent.keySet().iterator();
					while (it.hasNext()) {
						String key = it.next();
						value = value.replaceAll("(?i)\\{\\{\\s*"+key+"\\s*\\}\\}", jsonContent.getString(key));
					}
	
					JSONObject newNode = new JSONObject();
					newNode.put("node", node.getNode());
					newNode.put("font_color", node.getFontColour());
					newNode.put("value",value);
					
					map.put(node.getNode(), newNode);

				}
			}
			
		}
		
		param.put("msg_content", JSONObject.toJSONString(map));
	}
	/**
	 * 设置模板内容--wechat
	 * @param param
	 */
	private void setMsgContentForApp(JSONObject param) {
		Map<String,String> map = new HashMap<>();
		String msgContent = param.getString("msgContent");
		if (StringUtils.isNotBlank(msgContent)) {
			
			JSONObject jsonContent = JsonUtils.parseObject(param.get("msgContent"));
			Iterator<String> it = jsonContent.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				Object value = jsonContent.get(key);
				
				if (value instanceof Map) {
					value = ((Map) value).get("value");
				}
				else {
					value = value.toString();
				}
				
				map.put(key, value.toString());
			}
		}

		param.put("msg_content", map);
	}
	/**
	 * 根据不同的发送用户类型，获取最终需要发送的用户user_id
	 * @param param 
	 */
	private void setToUser(JSONObject param,String platformType) {
		logger.debug("setToUser："+JsonUtils.toJsonString(param));
		int userType = param.getIntValue("userType");
		if (userType == 1) {//就诊卡号
			JSONObject medicalParam = new JSONObject();
			medicalParam.put("card_no", param.get("to_user"));
			medicalParam.put("app_id", param.getString("app_id"));

			MedicalCardVo medicalCardVo = JsonUtils.parseObject(BaseService.callHumpFromInternal("yyt.base.medicalcard.by.cardno.and.appid.get", JsonUtils.toJsonString(medicalParam)).getResult(),MedicalCardVo.class);
			if (medicalCardVo == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"无此用户");
			}
			logger.debug("yyt.base.medicalcard.by.cardno.get返回："+JsonUtils.toJsonString(medicalCardVo));
			param.put("to_user", medicalCardVo.getOpenId());
		}
		else if (userType == 4) {//身份证
			JSONObject medicalParam = new JSONObject();
			medicalParam.put("card_no", param.get("to_user"));

			JSONObject jsonEhUser = JsonUtils.parseObject(BaseService.callHumpFromInternal("yyt.base.ehuser.by.cardno.get", JsonUtils.toJsonString(medicalParam)).getResult());
			if (jsonEhUser == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"无此用户");
			}
			logger.debug("yyt.base.ehuser.by.cardno.get返回："+JsonUtils.toJsonString(jsonEhUser));
			param.put("to_user", jsonEhUser.get(platformType.equals("alipay")?"alipay_id":"wechat_id"));
		}
		else if (userType == 5) {//手机号码
			JSONObject medicalParam = new JSONObject();
			medicalParam.put("mobile", param.get("to_user"));

			JSONObject jsonEhUser = JsonUtils.parseObject(BaseService.callHumpFromInternal("yyt.base.ehuser.by.mobile.get", JsonUtils.toJsonString(medicalParam)).getResult());
			if (jsonEhUser == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"无此用户");
			}
			logger.debug("yyt.base.ehuser.by.mobile.get返回："+JsonUtils.toJsonString(jsonEhUser));
			param.put("to_user", jsonEhUser.get(platformType.equals("alipay")?"alipay_id":"wechat_id"));
		}
		else if (userType == 3) {//订单号
			JSONObject registerParam = new JSONObject();
			registerParam.put("order_no", param.get("to_user"));
			JSONObject jsonRecord = JsonUtils.parseObject(BaseService.callUnderlineFromInternal("yyt.base.order.by.order.no.out.get", JsonUtils.toJsonString(registerParam)).getResult());
			if (jsonRecord == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"无此用户");
			}
			logger.debug("yyt.base.order.by.order.no.out.get返回："+JsonUtils.toJsonString(jsonRecord));
			param.put("to_user", jsonRecord.get("open_id"));
		}

	}

	
	/**
	 * 根据不同的发送用户类型，获取最终需要发送的用户user_id(新库)
	 * @param param 
	 */
	private void setToUserNew(JSONObject param,String appId) {
		logger.debug("setToUser："+JsonUtils.toJsonString(param));
		int userType = param.getIntValue("userType");
		if (userType == 1) {
			logger.debug("BaseService.getMeidcalCard:cardNo="+param.getString("to_user"));
			MedicalCardVo medical = BaseService.getMedicalCardByCardNo(param.getString("org_code"), param.getString("to_user"), "1",appId,null);
			logger.debug("BaseService.getMeidcalCard返回："+JsonUtils.toJsonString(medical));
			if (medical == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"找不到诊疗卡");
			}

			String userId = medical.getPatId();
			param.put("to_user", getOpenId(userId,appId));

		}
		else if (userType == 4) {//身份证
		
			logger.debug("BaseService.getPersonalUserByIdCardNo:idCardNo="+param.get("to_user"));
			PersonalUser personalUser = BaseService.getBaseClient().getPersonalUserByIdCardNo(param.getString("to_user"), (short) 1);
			logger.debug("getPersonalUserByIdCardNo返回:"+JsonUtils.toJsonString(personalUser));
			if (personalUser == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"无此用户");
			}
			
			
			String userId = personalUser.getId();
			param.put("to_user", getOpenId(userId,appId));
			
		}
		else if (userType == 5) {//手机号码
			
			logger.debug("BaseService.getPersonalUserByMobile:mobile="+param.get("to_user"));
			PersonalUser personalUser = BaseService.getBaseClient().getPersonalUserByMobile(param.getString("to_user"));
			logger.debug("getPersonalUserByMobile返回:"+JsonUtils.toJsonString(personalUser));
			if (personalUser == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_NOT_USER,"无此用户");
			}
			
			
			String userId = personalUser.getId();
			param.put("to_user", getOpenId(userId,appId));
			
		}
		else if (userType == 3) {//订单号
			
			logger.debug("BaseService.getOrderByOrderNo:orderNo="+param.get("to_user"));
			OrderExtVo orderExtVo = BaseService.getBaseClient().getOrderByOrderNo(param.getString("to_user"));
			logger.debug("getOrderByOrderNo返回:"+JsonUtils.toJsonString(orderExtVo));
			if (orderExtVo == null) {
				throw new CallException(ErrorCodeDefine.MESSAGE_COMMON,"无此订单");
			}
			
			String userId = orderExtVo.getUserId();
			param.put("to_user", getOpenId(userId,appId));
		}

	}
	
	/**
	 * 根据用户id和平台编码、拓展组织编码获取openId
	 * @param userId
	 * @param platformOrgAppCode
	 * @param devOrgCode
	 * @return
	 */
	private String getOpenId(String userId,String appId) {
	
		logger.debug("BaseService.getPersonalUserOpenid:userId="+userId+",appId="+appId);
		PersonalUserOpenid personalUserOpenid = BaseService.getBaseClient().getPersonalUserOpenid(userId, appId,null);
		logger.debug("BaseService.getPersonalUserOpenid返回:"+JsonUtils.toJsonString(personalUserOpenid));
		if (personalUserOpenid == null) {
			throw new CallException(ErrorCodeDefine.MESSAGE_NOT_FIND_OPENID, "找不到应用账号");
		}
		return personalUserOpenid.getOpenId();
	}
	
	/**
	 * 发送纯文本消息
	 * yyt.message.msg.text.send
	 * @param hospitalCode 医院编码
	 * @param platformType 平台类型
	 * @param userType 用户类型
	 * @param toUser 接收人
	 * @param msgContent 内容
	 */
	public String sendMsgText(String strJson) {
		try {
			logger.debug("sendMsgText:"+strJson);
			JSONObject param = JsonUtils.parseObject(strJson);
			

			//参数验证
			validParam(param,"org_app_code,platform_type,user_type,msg_content");
			if ( ! param.containsKey("org_code")) {
				param.put("org_code","");
			}
			param.put("hospital_code", param.getString("org_code"));
			
			boolean alipaySendFlag = false;//支付宝平台是否发送
			boolean wechatSendFlag = false;//微信平台是否发送
			String platformType = param.getString("platform_type").trim();
			if (platformType.equals("0")) {//所有平台都发
				alipaySendFlag = true;
				wechatSendFlag = true;
			}
			else {
				if (platformType.startsWith("1")) {
					//微信
					wechatSendFlag = true;
				}
				else if (platformType.startsWith("2")) {
					//支付宝
					alipaySendFlag = true;
				}
				else {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "平台类型错误");
				}
			}
			
			String strParam = JsonUtils.toJsonString(param);
			if (alipaySendFlag) {//支付宝
				//解析和设置发送的用户
				setToUser(param,"alipay");
				if (StringUtils.isNotBlank(param.getString("template_code"))) {
					TextTemplate textTemplate = getTextTemplate(param.getString("template_code"),param.getString("org_app_code"),param.getString("org_code"),2);
					
					String value = textTemplate.getMsgContent();
					value = value == null ? "" : value;
					JSONObject jsonContent = JsonUtils.parseObject(param.get("msg_content"));
					Iterator<String> it = jsonContent.keySet().iterator();
					while (it.hasNext()) {
						String key = it.next();
						value = value.replaceAll("(?i)\\{\\{\\s*"+key+"\\s*\\}\\}", jsonContent.getString(key));
					}
					param.put("msg_content", value);	
				}

				
				
				param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 2));
				
				logger.debug("yyt.alipay.alipaymessage.text.send调用参数："+JsonUtils.toJsonString(param));
				AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.text.send", JsonUtils.toJsonString(param));
			}
			
			//重新初始化，避免值混淆
			param = JsonUtils.parseObject(strParam);
			
			if (wechatSendFlag) {//微信
				//解析和设置发送的用户
				setToUser(param,"wechat");
				
				if (StringUtils.isNotBlank(param.getString("template_code"))) {
					TextTemplate textTemplate = getTextTemplate(param.getString("template_code"),param.getString("org_app_code"),param.getString("org_code"),1);
					
					String value = textTemplate.getMsgContent();
					value = value == null ? "" : value;
					JSONObject jsonContent = JsonUtils.parseObject(param.get("msg_content"));
					Iterator<String> it = jsonContent.keySet().iterator();
					while (it.hasNext()) {
						String key = it.next();
						value = value.replaceAll("(?i)\\{\\{\\s*"+key+"\\s*\\}\\}", jsonContent.getString(key));
					}
					param.put("msg_content", value);
				}
				
				param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 1));
				
				logger.debug("yyt.wechatpay.wechat.message.text.send用参数："+JsonUtils.toJsonString(param));
				//微信发送
				Response response = WechatPayService.callHumpFromInternal("yyt.wechatpay.wechat.message.text.send", JsonUtils.toJsonString(param));
				if ("0".equals(response.getResultCode())) {
					return "发送成功";
				}
				else {
					return  response.getResultMessage();
				}
			}
			
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
	}
	
	
	
	
	/**
	 * 发送单图文消息
	 * yyt.message.msg.image.send
	 * @param toUser 接收人ID
	 * @param platformType
	 * @param userType
	 * @param org_app_code
	 * @param desc 备注
	 * @param img_src 图片地址
	 * @param title 标题
	 * @param url 点击图片后转向的url
	 * @param actionName 链接文字
	 * */
	public String sendMsgImage(String strJson) {
		try {
			logger.debug("sendMsgImage:"+strJson);
			JSONObject param = JsonUtils.parseObject(strJson);
			
			//参数验证
			validParam(param,"org_app_code,platform_type,user_type,image_url,title");
			if (param.getString("title").length() > 15) {
				throw new CallException(ErrorCodeDefine.MESSAGE_PARAM,"标题不能超过15个字符");
			}
			
			boolean alipaySendFlag = false;//支付宝平台是否发送
			boolean wechatSendFlag = false;//微信平台是否发送
			String platformType = param.getString("platform_type");
			if (platformType.equals("0")) {//所有平台都发
				alipaySendFlag = true;
				wechatSendFlag = true;
			}
			else {
				if (platformType.startsWith("1")) {
					//微信
					wechatSendFlag = true;
				}
				else if (platformType.startsWith("2")) {
					//支付宝
					alipaySendFlag = true;
				}
				else {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "平台类型错误");
				}
			}
			
			String strParam = JsonUtils.toJsonString(param);
			if (alipaySendFlag) {//支付宝
				//解析和设置发送的用户
				setToUser(param,"alipay");
				
				param.put("payment_setting",this.getPaymentSetting(param.getString("org_app_code"), param.containsKey("org_code") ? param.getString("org_code") : "", 2));
				
				logger.debug("yyt.alipay.alipaymessage.image.send调用参数："+JsonUtils.toJsonString(param));
				AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.image.send", JsonUtils.toJsonString(param));
			}
			
			//重新初始化，避免值混淆
			param = JsonUtils.parseObject(strParam);
			
			if (wechatSendFlag) {//微信
				return "微信暂不支持";
			}
			
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
	}
	
	
	
	/**
	 * 精准推送 匹配推送
	 * yyt.message.msg.matcher.send
	 * @param hospitalCode
	 * @param platformType
	 * @param userType
	 * @param toUser 手机号码
	 * @param templateCode
	 */
	public String sendMsgMatcher(String strJson) {
		try {
			logger.debug("sendMsgTemplate:"+strJson);
			JSONObject param = JsonUtils.parseObject(strJson);
			
			//参数验证
			validParam(param,"hospital_code,platform_type,to_user,template_code");
			
			param.put("code", param.getString("template_code"));
			
			int platformType = param.getIntValue("platform_type");
			if (platformType == 0) {
				//获得需要发送消息的平台
				param.put("platform_code","");
			}
			else {
				if (platformType == 1) {
					param.put("platform_code", "wechat");
				}
				else if (platformType == 2) {
					param.put("platform_code", "alipay");
				}
				else {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "平台类型错误");
				}
			}
			List<MessageTemplate> listMessageTemplate = messageTemplateDao.findTemplateForSend(param.getString("template_code"),param.getString("hospital_code"),param.getString("platform_code"));
			logger.debug("listMessageTemplate:"+JsonUtils.toJsonString(listMessageTemplate));
			
			if (listMessageTemplate == null || listMessageTemplate.size() == 0) {
				return "没有找到匹配的消息模板";
			}
			
			String strParamBak = JsonUtils.toJsonString(param);
			int sendIndex = 0;
			
			for (MessageTemplate messageTemplate : listMessageTemplate) {
				//避免循环参数冲突
				if (sendIndex > 0) {
					param = JsonUtils.parseObject(strParamBak);
				}
				sendIndex++;
				
				String platformCode = messageTemplate.getPlatformCode();
				if (platformCode.equals("alipay")) {
					param.put("template_id", messageTemplate.getTemplateId());
					
					param.put("head_color",messageTemplate.getHeadColor());
					
					param.put("url", messageTemplate.getUrl());
					
					param.put("url",parseUrl(param.getString("url"),param));
					
					//解析和设置内容参数
					param.put("list_msg_template_content", new ArrayList<JSONObject>());

					//解析和设置发送的用户
					param.put("mobile",param.getString("to_user"));
					
					//解析和设置内容参数
					setMsgContentForAlipay(param);
					
					logger.debug("yyt.alipay.alipaymessage.template.by.mobile.send调用参数："+JsonUtils.toJsonString(param));
					
					AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.template.by.mobile.send", JsonUtils.toJsonString(param));
				}
				else if (platformCode.equals("wechat")) {
					//微信发送
				}
			}
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
	}
	
	
	/**
	 * 门诊待缴费消息推送
	 * yyt.message.msg.mzfee.send
	 * @param hospitalCode
	 * @param platformType
	 * @param userType
	 */
	public String sendMsgMzfee(String strJson) {
		try {
			logger.debug("sendMsgTemplate:"+strJson);
			JSONObject param = JsonUtils.parseObject(strJson);
			
			//固定模板编号
			param.put("code", "22000");
			param.put("template_code", "22000");
			
			//参数验证
			validParam(param,"hospital_code,platform_type,to_user,template_code");
			
			int platformType = param.getIntValue("platform_type");
			if (platformType == 0) {
				//获得需要发送消息的平台
				param.put("platform_code","");
			}
			else {
				if (platformType == 1) {
					param.put("platform_code", "wechat");
				}
				else if (platformType == 2) {
					param.put("platform_code", "alipay");
				}
				else {
					throw new CallException(ErrorCodeDefine.MESSAGE_PARAM, "平台类型错误");
				}
			}
			List<MessageTemplate> listMessageTemplate = messageTemplateDao.findTemplateForSend(param.getString("template_code"),param.getString("hospital_code"),param.getString("platform_code"));
			logger.debug("listMessageTemplate:"+JsonUtils.toJsonString(listMessageTemplate));
			
			if (listMessageTemplate == null || listMessageTemplate.size() == 0) {
				return "没有找到匹配的消息模板";
			}
			
			String strParamBak = JsonUtils.toJsonString(param);
			int sendIndex = 0;
			
			for (MessageTemplate messageTemplate : listMessageTemplate) {
				//避免循环参数冲突
				if (sendIndex > 0) {
					param = JsonUtils.parseObject(strParamBak);
				}
				sendIndex++;
				
				String platformCode = messageTemplate.getPlatformCode();
				if (platformCode.equals("alipay")) {
					param.put("template_id", messageTemplate.getTemplateId());
					
					param.put("head_color",messageTemplate.getHeadColor());
					
					param.put("url", messageTemplate.getUrl());
					
					param.put("url",parseUrl(param.getString("url"),param));
					
					//解析和设置内容参数
					List<JSONObject> listContent = new ArrayList<JSONObject>();
					JSONObject jsonMzfee = new JSONObject();
					jsonMzfee.put("money", param.get("money"));
					listContent.add(jsonMzfee);
					param.put("list_msg_template_content", listContent);

					//解析和设置发送的用户
					param.put("mobile",param.getString("to_user"));
					
					logger.debug("yyt.alipay.alipaymessage.template.send调用参数："+JsonUtils.toJsonString(param));
					
					AlipayService.callHumpFromInternal("yyt.alipay.alipaymessage.template.send", JsonUtils.toJsonString(param));
				}
				else if (platformCode.equals("wechat")) {
					//微信发送
				}
			}
			return "ok";
		} catch (CallException ce) {
			throw ce;
		} catch (Exception e) {
			throw new CallException(ErrorCodeDefine.MESSAGE_COMMON, "发送消息错误",e);
		}
	}


	/**
	 * 转发调用短信发送服务
	 * @param data
	 * @return
     */
	public ResponseObject sendMsgSms(String data) {
		return msgSmsService.sendMsgSms(data);
	}


	/**
	 * 根据条件获取消息模板内容
	 * @param datas
	 * @interfaceName: yyt.message.msg.app.template.get
	 * @return
	 */
	public Response getMsgAppTemplate(String datas) {
		logger.info("MsgAppServiceImpl.getMsgAppTemplat json-->" + datas);
		Response response = new Response();

		OrgAppTemplate template = JsonUtils.parseObject(datas, OrgAppTemplate.class);
		List<OrgAppTemplate> orgAppTemplates = orgAppTemplateDao.select(template);
		if(orgAppTemplates.size() > 0){
			response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE , JsonUtils.toJsonString(orgAppTemplates));
		}else{
			response.setResultCodeAndMessageAndResult(Response.FAILURE_CODE, "查无结果" , null);
		}

		return response;
	}




	/**
	 * 获取消息模板详细内容（骨科6期）
	 * @param datas
	 * @interfaceName: yyt.message.msg.app.template.list.get
	 * @return
	 */
	public ResponseObject getMsgAppTemplateList(String datas) {
		logger.info("MsgAppServiceImpl.getMsgAppTemplateList json-->" + datas);
		ResponseObject response = new ResponseObject();

		MsgTemplateListVo template = JsonUtils.parseObject(datas, MsgTemplateListVo.class);
		List<MsgTemplateListVo> msgAppTemplateList = orgAppTemplateDao.getMsgAppTemplateList(template.getPlatformId(), template.getPlatformOrgAppCode(), template.getTemplateCode() , template.getPlatformTemplateCode() , template.getPushType());
		if(msgAppTemplateList.size() > 0){
			response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE , msgAppTemplateList);
		}else{
			response.setResultCodeAndMessageAndResult(Response.FAILURE_CODE, "查无结果" , null);
		}

		return response;
	}



	/**
	 * 获取消息模板详细内容msg_image_template（骨科6期下拉列表展示）
	 * @param datas
	 * @interfaceName: yyt.message.msg.templates.get
	 * @return
	 */
	public ResponseObject getMsgTemplates(String datas) {
		logger.info("MsgAppServiceImpl.getMsgTemplates json-->" + datas);
		ResponseObject response = new ResponseObject();
		MsgTemplateListVo template = JsonUtils.parseObject(datas, MsgTemplateListVo.class);

		ImageTemplate imageTemplate = new ImageTemplate();
		if(StringUtils.isNotBlank(template.getLibraryTemplateCode())){
			imageTemplate.setTemplateCode(template.getLibraryTemplateCode());
		}

		List<MsgTemplateListVo> templateList = imageTemplateDao.getMsgImageTemplateList(imageTemplate.getTemplateCode());

		if(templateList.size() > 0){
			response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE , templateList);
		}else{
			response.setResultCodeAndMessageAndResult(Response.FAILURE_CODE, "查无结果" , null);
		}

		return response;
	}



	/**
	 * 新增消息模板详细内容（骨科6期）
	 * @param datas
	 * @interfaceName: yyt.message.msg.app.template.list.add
	 * @return
	 */
	public ResponseObject addMsgAppTemplateList(String datas) {
		logger.info("MsgAppServiceImpl.addMsgAppTemplateList json-->" + datas);
		ResponseObject response = new ResponseObject();
		MsgTemplateListVo template = JsonUtils.parseObject(datas, MsgTemplateListVo.class);

		//查询模板是否已存在
		ResponseObject msgResponse = getMsgAppTemplateList(JsonUtils.toJsonString(template));
		if("0".equals(msgResponse.getResultCode())){
			List<MsgTemplateListVo> listVos = (List<MsgTemplateListVo>) msgResponse.getResultObject();
			MsgTemplateListVo dbTemplate = listVos.get(0);

			logger.info("新增模板详情失败，已存在模板名称为："+ dbTemplate.getTemplateTitle() +", 编号为：" + dbTemplate.getLibraryTemplateCode() + "的主模板,请做对应修改");
			response.setResultCodeAndMessage(Response.FAILURE_CODE , "新增模板详情失败，已存在模板名称为："+ dbTemplate.getTemplateTitle() +", 编号为：" + dbTemplate.getLibraryTemplateCode() + "的主模板,请做对应修改");
			return response;
		}


		//查询相同类型的模板是否存在相同科室
		MsgTemplateListVo msgTemplate = new MsgTemplateListVo();
		msgTemplate.setPlatformId(template.getPlatformId());
		msgTemplate.setPlatformOrgAppCode(template.getPlatformOrgAppCode());
		msgTemplate.setPlatformTemplateCode(template.getPlatformTemplateCode());
		msgTemplate.setPushType(template.getPushType());
		ResponseObject deptMsgResponse = getMsgAppTemplateList(JsonUtils.toJsonString(msgTemplate));
		if("0".equals(deptMsgResponse.getResultCode())){
			List<MsgTemplateListVo> msgVos = (List<MsgTemplateListVo>) deptMsgResponse.getResultObject();
			for (MsgTemplateListVo msgVo : msgVos) {
				String msgStr = MsgTemplateUtils.deptDifferDatas(template.getPushDept(), msgVo.getPushDept());
				if(StringUtils.isNotBlank(msgStr)){
					logger.info("新增模板详情失败，该医院科室已存在相同类型模板："+ msgVo.getTemplateTitle() +", 编号为：" + msgVo.getLibraryTemplateCode() + "。存在科室列表：" + msgStr);
					response.setResultCodeAndMessage(Response.FAILURE_CODE , "新增模板详情失败，该医院科室已存在模板："+ msgVo.getTemplateTitle() +", 编号为：" + msgVo.getLibraryTemplateCode() + "。存在科室列表：" + msgStr);
					return response;
				}
			}
		}


		OrgAppTemplate orgAppTemplate = new OrgAppTemplate();
		orgAppTemplate.setId(PKGenerator.generateId());
		orgAppTemplate.setPlatformId(template.getPlatformId());
		orgAppTemplate.setPlatformName(template.getPlatformName());
		orgAppTemplate.setPlatformOrgAppName(template.getPlatformOrgAppName());
		orgAppTemplate.setPlatformOrgAppCode(template.getPlatformOrgAppCode());
		orgAppTemplate.setPlatformType(template.getPlatformType());
		orgAppTemplate.setPlatformTemplateCode(template.getPlatformTemplateCode());
		orgAppTemplate.setDevOrgId(template.getDevOrgId());
		orgAppTemplate.setDevOrgCode(template.getDevOrgCode());
		orgAppTemplate.setDevOrgName(template.getDevOrgName());
		orgAppTemplate.setLibraryTemplateType(template.getLibraryTemplateType());
		orgAppTemplate.setLibraryTemplateCode(template.getTemplateCode());
		orgAppTemplate.setPushDept(template.getPushDept());
		orgAppTemplate.setPushType(template.getPushType());
		orgAppTemplate.setDataSource(template.getDataSource());
		orgAppTemplate.setPushCount(0);
		orgAppTemplate.setUrlClickCount(0);
		orgAppTemplateDao.insert(orgAppTemplate);

		//根据模板code查询消息列表信息
		ImageTemplate imageTemplate = new ImageTemplate();
		imageTemplate.setTemplateCode(template.getTemplateCode());
		List<ImageTemplate> imageTemplates = imageTemplateDao.select(imageTemplate);
		if(imageTemplates.size() > 0){
			imageTemplate = imageTemplates.get(0);

			ImageTemplateList imageTemplateList = new ImageTemplateList();
			imageTemplateList.setImageTemplateId(imageTemplate.getId());
			List<ImageTemplateList> imageTemplateLists = imageTemplateListDao.select(imageTemplateList);
			if(imageTemplateLists.size() > 0){
				imageTemplateList = imageTemplateLists.get(0);
				imageTemplateList.setImageTemplateId(imageTemplate.getId());
				imageTemplateList.setImageTemplateCode(imageTemplate.getTemplateCode());
				imageTemplateList.setImageUrl(template.getImageUrl());
				imageTemplateList.setActionUrl(template.getActionUrl());
				imageTemplateList.setImageContent(template.getImageContent());
				imageTemplateList.setImageTitle(template.getImageTitle());
				imageTemplateList.setActionName(template.getActionName());
				imageTemplateListDao.update(imageTemplateList);

				response.setResultCodeAndMessage(Response.SUCCESS_CODE , "该模板已存在，更新模板成功，模板编号为：" + imageTemplate.getTemplateCode());
			}
		}else{
			logger.info("新增模板详情失败,根据library_template_code:" + template.getLibraryTemplateCode() +", 未查询到对应模板.");
			response.setResultCodeAndMessage(Response.FAILURE_CODE , "新增模板详情失败,根据library_template_code:" + template.getLibraryTemplateCode() +", 未查询到对应模板,请检查后台配置");
		}

		return response;
	}



	/**
	 * 修改消息模板详细内容（骨科6期）
	 * @param datas
	 * @interfaceName: yyt.message.msg.app.template.list.update
	 * @return
	 */
	public ResponseObject updateMsgAppTemplateList(String datas) {
		logger.info("MsgAppServiceImpl.updateMsgAppTemplateList json-->" + datas);
		ResponseObject response = new ResponseObject();
		MsgTemplateListVo template = JsonUtils.parseObject(datas, MsgTemplateListVo.class);

		Short pushType = null;

		//查出需要修改模板
		OrgAppTemplate orgAppTemplate = new OrgAppTemplate();
		orgAppTemplate.setPlatformId(template.getPlatformId());
		orgAppTemplate.setPlatformOrgAppCode(template.getPlatformOrgAppCode());
		orgAppTemplate.setLibraryTemplateCode(template.getOldLibraryTemplateCode());
		List<OrgAppTemplate> orgAppTemplates = orgAppTemplateDao.select(orgAppTemplate);
		if(orgAppTemplates.size() > 0){
			orgAppTemplate = orgAppTemplates.get(0);
			pushType = orgAppTemplate.getPushType();
		}


		//查询模板是否已存在
		if(!template.getLibraryTemplateCode().equals(template.getOldLibraryTemplateCode()) && pushType != template.getPushType()){
			ResponseObject msgResponse = getMsgAppTemplateList(JsonUtils.toJsonString(template));
			if("0".equals(msgResponse.getResultCode())){
				List<MsgTemplateListVo> listVos = (List<MsgTemplateListVo>) msgResponse.getResultObject();
				template = listVos.get(0);
				logger.info("更新模板详情失败，已存在模板名称为："+ template.getTemplateTitle() +", 编号为：" + template.getLibraryTemplateCode() + "的主模板,请做对应修改");
				response.setResultCodeAndMessage(Response.FAILURE_CODE , "更新模板详情失败，已存在模板名称为："+ template.getTemplateTitle() +", 编号为：" + template.getLibraryTemplateCode() + "的主模板,请做对应修改");
				return response;
			}
		}


		//查询相同类型的模板是否存在相同科室
		OrgAppTemplate  appTemplate = new OrgAppTemplate();
		appTemplate.setPlatformId(template.getPlatformId());
		appTemplate.setPlatformOrgAppCode(template.getPlatformOrgAppCode());
		appTemplate.setPlatformTemplateCode(template.getPlatformTemplateCode());
		appTemplate.setPushType(template.getPushType());
		List<OrgAppTemplate> appTemplates = orgAppTemplateDao.select(appTemplate);
		for (OrgAppTemplate exOrgAppTemplate : appTemplates) {
			if(!exOrgAppTemplate.getLibraryTemplateCode().equals(template.getOldLibraryTemplateCode()) && StringUtils.isNotBlank(exOrgAppTemplate.getPushDept())){
				String msgStr = MsgTemplateUtils.deptDifferDatas(template.getPushDept(), exOrgAppTemplate.getPushDept());
				if(StringUtils.isNotBlank(msgStr)){
					logger.info("更新模板详情失败，该医院科室已存在相同类型模板, 编号为：" + exOrgAppTemplate.getLibraryTemplateCode() + "。存在科室列表：" + msgStr);
					response.setResultCodeAndMessage(Response.FAILURE_CODE , "更新模板详情失败，该医院科室已存在模板, 编号为：" + exOrgAppTemplate.getLibraryTemplateCode() + "。存在科室列表：" + msgStr);
					return response;
				}
			}
		}


		if(orgAppTemplates.size() > 0){
			orgAppTemplate.setPlatformId(template.getPlatformId());
			orgAppTemplate.setPlatformName(template.getPlatformName());
			orgAppTemplate.setPlatformOrgAppName(template.getPlatformOrgAppName());
			orgAppTemplate.setPlatformOrgAppCode(template.getPlatformOrgAppCode());
			orgAppTemplate.setPlatformType(template.getPlatformType());
			orgAppTemplate.setPlatformTemplateCode(template.getPlatformTemplateCode());
			orgAppTemplate.setDevOrgId(template.getDevOrgId());
			orgAppTemplate.setDevOrgCode(template.getDevOrgCode());
			orgAppTemplate.setDevOrgName(template.getDevOrgName());
			orgAppTemplate.setLibraryTemplateType(template.getLibraryTemplateType());
			orgAppTemplate.setLibraryTemplateCode(template.getTemplateCode());
			orgAppTemplate.setPushDept(template.getPushDept());
			orgAppTemplate.setPushType(template.getPushType());
			orgAppTemplate.setDataSource(template.getDataSource());
			orgAppTemplateDao.update(orgAppTemplate);

			//根据模板code查询消息列表信息
			ImageTemplate imageTemplate = new ImageTemplate();
			imageTemplate.setTemplateCode(template.getTemplateCode());
			List<ImageTemplate> imageTemplates = imageTemplateDao.select(imageTemplate);
			if(imageTemplates.size() > 0){
				imageTemplate = imageTemplates.get(0);

				ImageTemplateList imageTemplateList = new ImageTemplateList();
				imageTemplateList.setImageTemplateId(imageTemplate.getId());
				List<ImageTemplateList> imageTemplateLists = imageTemplateListDao.select(imageTemplateList);

				if(imageTemplateLists.size() > 0){
					imageTemplateList = imageTemplateLists.get(0);
					imageTemplateList.setImageTitle(template.getImageTitle());
					imageTemplateList.setImageTemplateCode(imageTemplate.getTemplateCode());
					imageTemplateList.setImageUrl(template.getImageUrl());
					imageTemplateList.setActionUrl(template.getActionUrl());
					imageTemplateList.setImageContent(template.getImageContent());
					imageTemplateList.setActionName(template.getActionName());
					imageTemplateListDao.update(imageTemplateList);
				}

				response.setResultCodeAndMessage(Response.SUCCESS_CODE , "更新成功");
			}
		}else{
			logger.info("根据模板code获取模板失败");
			response.setResultCodeAndMessage(Response.FAILURE_CODE , "根据模板code获取模板失败");
		}


		return response;
	}


	/**
	 * 删除消息模板（骨科6期）
	 * @param datas
	 * @interfaceName: yyt.message.msg.app.template.list.delete
	 * @return
	 */
	public ResponseObject deleteMsgAppTemplateList(String datas) {
		logger.info("MsgAppServiceImpl.deleteMsgAppTemplateList json-->" + datas);
		ResponseObject response = new ResponseObject();
		MsgTemplateListVo template = JsonUtils.parseObject(datas, MsgTemplateListVo.class);

		OrgAppTemplate orgAppTemplate = new OrgAppTemplate();
		orgAppTemplate.setPlatformId(template.getPlatformId());
		orgAppTemplate.setPlatformOrgAppCode(template.getPlatformOrgAppCode());
		orgAppTemplate.setLibraryTemplateCode(template.getLibraryTemplateCode());
		List<OrgAppTemplate> orgAppTemplates = orgAppTemplateDao.select(orgAppTemplate);
		if(orgAppTemplates.size() > 0){
			OrgAppTemplate appTemplate = orgAppTemplates.get(0);
			orgAppTemplateDao.delete(appTemplate);
			response.setResultCodeAndMessage(Response.SUCCESS_CODE , "删除成功");
		}else{
			logger.info("删除失败！根据platformId：" + template.getPlatformId() +",platformOrgAppCode:" + template.getPlatformOrgAppCode() + ",libraryTemplateCode:" + template.getLibraryTemplateCode() + "   --- 查无数据");
			response.setResultCodeAndMessage(Response.FAILURE_CODE , "删除失败！根据platformId：" + template.getPlatformId() +",platformOrgAppCode:" + template.getPlatformOrgAppCode() + ",libraryTemplateCode:" + template.getLibraryTemplateCode() + "   --- 查无数据");
		}

		return response;
	}


	/**
	 * 关注后消息推送次数增加（骨科6期）
	 * @param datas
	 * @interfaceName: yyt.message.msg.app.template.count.add
	 * @return
	 */
	public ResponseObject addMsgAppTemplateCount(String datas) {
		logger.info("MsgAppServiceImpl.addMsgAppTemplateCount json-->" + datas);
		ResponseObject response = new ResponseObject();
		Map<String,String> param = JsonUtils.parseObject(datas, Map.class);
		String addType = param.get("add_type");		//增加推送类型 1：推送次数  2：链接跳转次数

		OrgAppTemplate orgAppTemplate = JsonUtils.parseObject(datas, OrgAppTemplate.class);

		List<OrgAppTemplate> orgAppTemplates = orgAppTemplateDao.select(orgAppTemplate);
		if(orgAppTemplates.size() > 0){
			orgAppTemplate = orgAppTemplates.get(0);

			if("1".equals(addType)){
				orgAppTemplate.setPushCount(orgAppTemplate.getPushCount() + 1);
			}else{
				orgAppTemplate.setUrlClickCount(orgAppTemplate.getUrlClickCount() + 1);
			}

			orgAppTemplateDao.update(orgAppTemplate);
			response.setResultCodeAndMessage(Response.SUCCESS_CODE , "更新成功");
		}else{
			logger.info("根据传入id获取模板失败 id:" + param.get("id"));
			response.setResultCodeAndMessage(Response.FAILURE_CODE , "根据传入id获取模板失败 id:" + param.get("id"));
		}

		return response;
	}


}
